#region license
# This file is part of Grawlix.
# 
# Grawlix is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as
# published by the Free Software Foundation, either version 3 of
# the License, or (at your option) any later version.
# 
# Grawlix is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public
# License along with Grawlix.  If not, see
# <http://www.gnu.org/licenses/>.
#endregion

"""A GUI wrapping a view into a map."""

namespace Grawlix.Application.Gui
import Grawlix
import Grawlix.Meta
import Grawlix.Services
import Grawlix.Services.Rendering
import System

[Disposable]
transient class MapView(Control):
"""A control used to peer into a piece of a map."""
	
	override def Render([required] device as IRenderDevice,
	                    area as Rect):
	"""
	Render this view into the specified map.
	Param device: The device to render with.
	Param area: The area on the screen to render to.
	"""
		# Difficult because it has to
		# go through an AppDomain boundary
		if _map is not null and _map.Ready:
			# assume clipping has already been done
			using device.Zoom(area, Camera):
				_map.DirectAccess[of IRenderableArea](). \
					Render(device, Camera)
	
	override def OnMouseEnter(position as Vector,
	                          bounds as Rect):
	"""
	Pass the event to the map.
	Param position: The position in window coordinates.
	Param bounds: The area of the control in window coordinates.
	"""
		position = bounds.ProjectPoint(position, Camera)
		_map.Post(MouseEnterInputMessage(position))
	
	override def OnMouseLeave(position as Vector,
	                          bounds as Rect):
	"""
	Pass the event to the map.
	Param position: The last known position in window coordinates.
	Param bounds: The area of the control in window coordinates.
	"""
		position = bounds.ProjectPoint(position, Camera)
		_map.Post(MouseLeaveInputMessage(position))
	
	override def OnMouseMove(position as Vector,
	                         delta as Vector,
	                         bounds as Rect):
	"""
	Pass the event to the map.
	Param position: The position in window coordinates.
	Param delta: The change since the last movement event.
	Param bounds: The area of the control in window coordinates.
	"""
		position = bounds.ProjectPoint(position, Camera)
		delta = bounds.ProjectDisplacement(delta, Camera)
		_map.Post(MouseMoveInputMessage(position, delta))
	
	override def OnMouseWheel(position as Vector,
	                          ticks as int,
	                          bounds as Rect):
	"""
	Pass the event to the map.
	Param ticks: The number of ticks moved.
	Param position: The position in window coordinates.
	Param bounds: The area of the control in window coordinates.
	"""
		position = bounds.ProjectPoint(position, Camera)
		_map.Post(MouseWheelInputMessage(position, ticks))
	
	override def OnMouseUp(position as Vector,
	                       code as int,
	                       bounds as Rect):
	"""
	Pass the event to the map.
	Param code: The mouse event code.
	Param position: The position in window coordinates.
	Param bounds: The area of the control in window coordinates.
	"""
		position = bounds.ProjectPoint(position, Camera)
		_map.Post(MouseUpInputMessage(position, code))
	
	override def OnMouseDown(position as Vector,
	                         code as int,
	                         bounds as Rect):
	"""
	Pass the event to the map.
	Param code: The mouse event code.
	Param position: The position in window coordinates.
	Param bounds: The area of the control in window coordinates.
	"""
		position = bounds.ProjectPoint(position, Camera)
		_map.Post(MouseDownInputMessage(position, code))
	
	def ChangeMap([required]where as Domain, camera as Rect):
	"""
	View a different map.
	Param where: The map to view.
	Param camera: The area on the map to view.
	"""
		_map = where
		_camera = camera
	
	def ClearMap():
	"""View no map."""
		_map = null
		_camera = Rect(0, 0, 0, 0)
	
	[property(Camera)]
	private _camera = Rect(0, 0, 0, 0)
	"""The area of the map that this view is looking at."""
	
	[getter(Map)]
	[IgnoreDisposal]
	private _map as Domain
	"""The map that this control views."""
	
	
